package com.ushine.web.template.complex.facade.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ushine.web.base.model.relation.RoleAndFunctionPermissionDO;
import com.ushine.web.base.model.relation.UserAndRoleDO;
import com.ushine.web.base.model.system.UserDO;
import com.ushine.web.base.service.IRoleAndFunPermissionService;
import com.ushine.web.base.service.IUserAndRoleService;
import com.ushine.web.base.service.IUserService;
import com.ushine.web.template.complex.facade.IDemoFacade;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author: yls
 * @Date 2022/2/8 16:45
 * @Description: service包装层的实现
 * @Transactional(readOnly = true)应用场合：
 * 如果你一次执行单条查询语句，则没有必要启用事务支持，数据库默认支持SQL执行期间的读一致性；
 * 如果你一次执行多条查询语句，例如统计查询，报表查询，在这种场景下，多条查询SQL必须保证整体的读一致性，否则，在前条SQL查询之后，后条SQL查询之前，数据被其他用户改变，则该次整体的统计查询将会出现读数据不一致的状态，此时，应该启用事务支持。
 * 【注意是一次执行多次查询来统计某些信息，这时为了保证数据整体的一致性，要用只读事务】
 * @Version 1.0
 **/
@Service
public class DemoFacadeImpl implements IDemoFacade {

    @Resource
    private IUserService userService;

    @Resource
    private IUserAndRoleService userRoleService;

    @Resource
    private IRoleAndFunPermissionService rolePermissionService;

    @Override
    @Transactional(readOnly = true)
    public List<RoleAndFunctionPermissionDO> listPermissions(String username) {
        /*
         * 1、根据用户名获取用户信息
         */
        UserDO userDO = userService.getUserBaseInfo(username);
        userDO = Optional.ofNullable(userDO).orElse(new UserDO());

        /*
         * 2、获取对应的角色 id
         */
        LambdaQueryWrapper<UserAndRoleDO> roleQueryWrapper = new LambdaQueryWrapper<UserAndRoleDO>()
                .eq(UserAndRoleDO::getUserId, userDO.getUserId());
        List<UserAndRoleDO> userRoles = userRoleService.list(roleQueryWrapper);
        // 组装id集合
        List<Long> roleIds = userRoles.stream().map(UserAndRoleDO::getRoleId).collect(Collectors.toList());
        roleIds = Optional.ofNullable(roleIds).orElse(new ArrayList<>(0));
        if (roleIds.isEmpty()) {
            return new ArrayList<>(0);
        }
        /*
         * 3、通过角色id获取对应的权限信息
         */
        LambdaQueryWrapper<RoleAndFunctionPermissionDO> permissionQueryWrapper = new LambdaQueryWrapper<RoleAndFunctionPermissionDO>()
                .in(RoleAndFunctionPermissionDO::getRoleId, roleIds);
        List<RoleAndFunctionPermissionDO> list = rolePermissionService.list(permissionQueryWrapper);
        return Optional.ofNullable(list).orElse(new ArrayList<>());
    }
}
